package org.imsetal.iluserservice.service;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.IncorrectClaimException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.annotation.Resource;
import org.imsetal.iluserservice.mapper.UserMapper;
import org.imsetal.iluserservice.pojo.User;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class UserService {
    private static final String PASSWORD_REGEX="^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d).{8,}$";
    private static final Long TOKEN_EXPIRES_TIME = (long) (1*24*60*60*1000);
    private static final String TOKEN_ISSUER="il-user-service-tu7xds";
    private static final String TOKEN_SECRET = "y6xagpe";

    @Resource
    UserMapper userMapper;

    public String login(String username, String password) {
        if(checkUserExist(username)){
            if(checkUserPasswordExist(username)){
                if(checkUserLoginInfo(username,password)){
                    return "success";
                }else{
                    return "用户名或密码错误";
                }
            }else{
                return "success";
            }
        }else{
            return "用户名或密码错误";
        }
    }

    public String register(String username, String password) {
        if(!checkPasswordFormat(password))return "密码格式错误";
        if(checkUserExist(username))return "用户已存在";

        User user = new User();
        user.setUsername(username);
        user.setUserpassword(password);
        userMapper.insert(user);
        return "success";
    }

    public User getUserInfo(String username){
        if(!checkUserExist(username))return null;

        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        user.setUserpassword(null);
        return user;
    }

    public boolean checkUserExist(String username) {
        QueryWrapper wrapper=new QueryWrapper<>();
        wrapper.eq("username",username);
        List<User> users=userMapper.selectList(wrapper);
        return users.size()>0;
    }

    public boolean checkUserExist(Long userid) {
        QueryWrapper wrapper=new QueryWrapper<>();
        wrapper.eq("userid",userid);
        List<User> users=userMapper.selectList(wrapper);
        return users.size()>0;
    }

    public boolean checkUserPasswordExist(String username) {
        QueryWrapper wrapper=new QueryWrapper<>();
        wrapper.eq("username",username);
        List<User> users=userMapper.selectList(wrapper);
        return users.get(0).getUserpassword()!=null;
    }

    public boolean checkUserLoginInfo(String username, String userpassword){
        QueryWrapper wrapper=new QueryWrapper<>();
        wrapper.eq("username",username);
        List<User> users=userMapper.selectList(wrapper);
        return users.get(0).getUserpassword().equals(userpassword);
    }

    public boolean checkPasswordFormat(String password) {
        return password.matches(PASSWORD_REGEX);
    }

    public String createUserLoginToken(String username, String password) {
        User user=userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        String token;
        Date expiresAt = new Date(System.currentTimeMillis() + TOKEN_EXPIRES_TIME);
        token= JWT.create()
                .withIssuer(TOKEN_ISSUER)
                .withClaim("userid",user.getUserid())
                .withClaim("username",username)
                .withClaim("userpassword",password)
                .withExpiresAt(expiresAt)
                .sign(Algorithm.HMAC256(TOKEN_SECRET));
        return token;
    }

    public boolean checkUserIdToken(String token) {
        try {
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer(TOKEN_ISSUER).build();
            DecodedJWT jwt = jwtVerifier.verify(token);
            // 验证token颁发来源
            String issuer = jwt.getIssuer();
            if (!issuer.equals(TOKEN_ISSUER)) return false;
            // 验证token登录信息
            Long userid = jwt.getClaim("userid").asLong();
            String username = jwt.getClaim("username").asString();

            User user = userMapper.selectOne(new QueryWrapper<User>().eq("userid", userid));
            if (user.getUsername().equals(username)){
                return true;
            }else{
                return false;
            }
        }catch (IncorrectClaimException e){
            return false;
        }catch (TokenExpiredException e){
            return false;
        }
    }

    public boolean checkUserLoginToken(String token) {
        try {
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer(TOKEN_ISSUER).build();
            DecodedJWT jwt = jwtVerifier.verify(token);
            // 验证token颁发来源
            String issuer = jwt.getIssuer();
            if (!issuer.equals(TOKEN_ISSUER)) return false;
            // 验证token登录信息
            String username = jwt.getClaim("username").asString();
            String userpassword = jwt.getClaim("userpassword").asString();
            if (checkUserExist(username)) {
                if (checkUserPasswordExist(username)) {
                    if (checkUserLoginInfo(username, userpassword)) {
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return true;
                }
            } else {
                return false;
            }
        }catch (IncorrectClaimException e){
            return false;
        }catch (TokenExpiredException e){
            return false;
        }
    }

    public String getUsernameByToken(String token) {
        try {
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer(TOKEN_ISSUER).build();
            DecodedJWT jwt = jwtVerifier.verify(token);
            // 验证token颁发来源
            String issuer = jwt.getIssuer();
            if (!issuer.equals(TOKEN_ISSUER)) return null;
            // 验证token登录信息
            String username = jwt.getClaim("username").asString();
            String userpassword = jwt.getClaim("userpassword").asString();
            if (checkUserExist(username)) {
                if (checkUserPasswordExist(username)) {
                    if (checkUserLoginInfo(username, userpassword)) {
                        return username;
                    } else {
                        return null;
                    }
                } else {
                    return username;
                }
            } else {
                return null;
            }
        }catch (IncorrectClaimException e){
            return null;
        }catch (TokenExpiredException e){
            return null;
        }
    }
}
